package com.atqh.srrt.chicken.controller.LiveChatWS;

/**
 * @作者：大叔azhe
 * @api：详细描述
 * @创建时间：17:49 2024/2/25
 */


import com.atqh.srrt.chicken.config.WebsocketConfig;
import com.atqh.srrt.chicken.domain.SysUser;
import com.atqh.srrt.chicken.domain.ws.Message;
import com.atqh.srrt.chicken.service.LoginService;
import com.atqh.srrt.chicken.utils.MessageUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

//如果登录用户的信息存在httpSession里面，想获取HttpSession对象，则用下面这个方法
//@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)
@ServerEndpoint(value = "/chat",configurator = WebsocketConfig.class)
@Component
@Slf4j
@CrossOrigin
public class ChatEndpoint {

    static LoginService loginService;
    //用来存储每个用户客户端对象的ChatEndpoint对象

    @Autowired  //关键点3
    public void setUserService (LoginService loginService){
        ChatEndpoint.loginService = loginService;
    }
    private static Map<String, ChatEndpoint> onlineUsers = new ConcurrentHashMap<>();

    //声明session对象，通过对象可以发送消息给指定的用户
    private Session session;

    //声明HttpSession对象，我们之前在HttpSession对象中存储了用户名
//    private HttpSession httpSession;

    //连接建立
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        System.out.println("WebSocket连接后端成功！");
        this.session = session;
/*        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        this.httpSession = httpSession;
        //存储登陆的对象
        String username = (String)httpSession.getAttribute("user");*/


        String token = (String) session.getUserProperties().get("token");
        SysUser sysUser = ChatEndpoint.loginService.checkToken(token);
//        UserThreadLocal.put(sysUser);

        onlineUsers.put(sysUser.getId() + "-" + sysUser.getNickname(), this);

        //将当前在线用户的用户名推送给所有的客户端
        //1 获取消息
        String message = MessageUtils.getMessage(true, null, null,null,getNames());
        //2 调用方法进行系统消息的推送
        broadcastAllUsers(message);
    }

    private void broadcastAllUsers(String message) {
        try {
            //将消息推送给所有的客户端
            Set<String> names = onlineUsers.keySet();
            for (String name : names) {
                ChatEndpoint chatEndpoint = onlineUsers.get(name);
                chatEndpoint.session.getBasicRemote().sendText(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //返回在线用户名
    private Set<String> getNames() {
        System.out.println(onlineUsers.keySet());
        return onlineUsers.keySet();
    }

    //收到消息
    @OnMessage
    public void onMessage(String message, Session session) {
        //将数据转换成对象
        try {
            System.out.println(message);
            ObjectMapper mapper = new ObjectMapper();
            Message mess = mapper.readValue(message, Message.class);
            System.out.println(mess);
            String toName = mess.getToName();
            String data = mess.getMessage();
//            String username = (String) httpSession.getAttribute("user");
            //ThreadLocal无法获取到相应的用户，不知道为啥
//            SysUser sysUser = UserThreadLocal.get();
            String token = (String) session.getUserProperties().get("token");
            SysUser sysUser = ChatEndpoint.loginService.checkToken(token);
            System.out.println(sysUser);
            String username=sysUser.getId()+"-"+sysUser.getNickname();
            String avatar=sysUser.getAvatar();
            Boolean admin=sysUser.getAdmin();
            String resultMessage = MessageUtils.getMessage(false, username, avatar,admin,data);
            //发送数据
//            onlineUsers.get(toName).session.getBasicRemote().sendText(resultMessage);
            //2 调用方法进行系统消息的推送
            broadcastAllUsers(resultMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //关闭
    @OnClose
    public void onClose(Session session) {
//        String username = (String) httpSession.getAttribute("user");
//        SysUser sysUser = UserThreadLocal.get();
        String token = (String) session.getUserProperties().get("token");
        SysUser sysUser = ChatEndpoint.loginService.checkToken(token);
        String username=sysUser.getId()+"-"+sysUser.getNickname();
        //从容器中删除指定的用户
        onlineUsers.remove(username);
//        log.info("登录的用户{}从线程池里被删除了",UserThreadLocal.get());
//        /**
//         *@作者：大叔azhe
//         *@api：如果不删除，会有内存泄露风险,因为jvm的原因，强弱引用被删除时机不同，容易导致弱引用的key被删除了，但value是强引用，永远留在了内存中
//         *@创建时间：10:29 2022/8/18
//         */
//        UserThreadLocal.remove();
//        MessageUtils.getMessage(true, null, getNames());
    }
}

